﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once
#include "OwnerPtr.h"
#include <vector>
#include "IOffsetCoedgeMap.h"
#include "WeakReferenceable.h"
#include "GcmpGeometryInterface.h"


namespace gcmp
{
    class IPolygon;
    class IPolyCurve;
    class ISurface;
    class ICurve2d;

    class IOffset : public WeakReferenceable
    {
    public:
        virtual ~IOffset() {}

        /// \brief  对Polygon做offset
        /// \param IPolygon* pInitPolygon          初始多边形
        /// \param double dOffsetDis                 Offset的距离(为正值时，在右手坐标系下，沿polygon法向正向向下看，外环向左侧偏置，内环向外侧偏置；负值反之)
        /// \param OffsetConnectOption connectMode   相邻边之间的连接方式，是延长求交还是用圆弧过渡
        /// \param double dEpsilon                   偏移过程中判断是否共点的容差，通常给: DISTANCE_ITERATION_EPS = 1E-4
        /// \param OwnerPtr<IPolygon> &opOffsetPolygon 偏移后的Polygon
        /// \return OffsetCoedgeMap 偏移前后，边的对应关系
        virtual OwnerPtr<IOffsetCoedgeMap> Offset(const IPolygon* pInitPolygon, OwnerPtr<IPolygon> &opOffsetPolygon, double dOffsetDis, OffsetConnect connectType, double dEpsilon) const = 0;

        /// \brief  对Polygon做offset
        /// \param IPolygon* pInitPolygon         初始多边形
        /// \param dOffsetDis    Offset的距离数组，对于初始多边形的每条边，可以用不同距离做Offset，顺序填充这个距离数组即可
        ///                                              (为正值时，在右手坐标系下，沿polygon法向正向向下看，外环向左侧偏置，内环向外侧偏置；负值反之)
        /// \param OffsetConnectOption connectMode   相邻边之间的连接方式，是延长求交还是用圆弧过渡
        /// \param dEpsilon                   偏移过程中判断是否共点的容差，通常给: DISTANCE_ITERATION_EPS = 1E-4
        /// \param &opOffsetPolygon 偏移后的Polygon
        /// \return OffsetCoedgeMap 偏移前后，边的对应关系
        virtual  OwnerPtr<IOffsetCoedgeMap> Offset(const IPolygon* pOriginalPolygon, OwnerPtr<IPolygon> &opOffsetPolygon, const std::vector<double>& offsetDistance, OffsetConnect connectType, double dEpsilon)const = 0;
        
        /// \brief  对CoedgeList 做offset， 不处理自交
        /// \param const IPolyCurve* pInitCoedgeList         初始曲线集
        /// \param double dOffsetDis                            Offset的距离(为正值时，在右手坐标系下，沿CoedgeList法向正向向下看，沿着CoedgeList中曲线的箭头方向，向左侧偏置；负值反之)
        /// \param OffsetConnect connectType              相邻边之间的连接方式，是延长求交还是用圆弧过渡
        /// \param double dEpsilon                              偏移过程中判断是否共点的容差，通常给: DISTANCE_ITERATION_EPS = 1E-4
        /// \param OwnerPtr<IPolyCurve> &opOffsetCoedgeList 偏移后曲线集
        /// \return OffsetCoedgeMap 偏移前后，边的对应关系
        virtual OwnerPtr<IOffsetCoedgeMap> Offset(const IPolyCurve* pInitCoedgeList, OwnerPtr<IPolyCurve> &opOffsetCoedgeList, double dOffsetDis, OffsetConnect connectType, double dEpsilon) const = 0;
        
        /// \brief  对CoedgeList做offset， 不处理自交, 新算法接口返回结果为多段线列表
        /// \param const IPolyCurve* pInitCoedgeList         初始曲线集
        /// \param double dOffsetDis                            Offset的距离(为正值时，在右手坐标系下，沿CoedgeList法向正向向下看，沿着CoedgeList中曲线的箭头方向，向左侧偏置；负值反之)
        /// \param OffsetConnect connectType              相邻边之间的连接方式，是延长求交还是用圆弧过渡
        /// \param double dEpsilon                              偏移过程中判断是否共点的容差，通常给: DISTANCE_ITERATION_EPS = 1E-4
        /// \param OwnerPtr<IPolyCurve> &opOffsetPolyCurves 偏移后多段线列表集合
        /// \return OffsetCoedgeMap 偏移前后，边的对应关系
        virtual OwnerPtr<IOffsetCoedgeMap> Offset(const IPolyCurve* pInitCoedgeList, std::vector<OwnerPtr<IPolyCurve>> &opOffsetPolyCurves, double dOffsetDis, OffsetConnect connectType, double dEpsilon) const = 0;

        /// \brief  偏移多段线， 不处理自交
        ///
        /// \param pOriginalPolyCurve         初始多段线
        /// \param opOffsetPolyCurve          偏移后多段线
        /// \param offsetDistance             Offset的距离数组，对于初始多段线的每条边，可以用不同距离做Offset，顺序填充这个距离数组即可
        ///                                              (为正值时，在右手坐标系下，沿polygon法向正向向下看，外环向左侧偏置，内环向外侧偏置；负值反之)
        /// \param connectType                相邻边之间的连接方式，是延长求交还是用圆弧过渡
        /// \param dEpsilon                   偏移过程中判断是否共点的容差

        /// \return 偏移前后，边的对应关系
        virtual OwnerPtr<IOffsetCoedgeMap> Offset(const IPolyCurve* pOriginalPolyCurve, OwnerPtr<IPolyCurve> &opOffsetPolyCurve, const std::vector<double>& offsetDistance, OffsetConnect connectType, double dEpsilon) const = 0;


        /// \brief  对ISurface 做offset， 不处理自交
        /// \param const ISurface* pSurface         初始曲面
        /// \param double offsetDis         正:沿曲面法向; 负:沿曲面负法向                
        /// \return OwnerPtr<ISurface>     偏移后的曲面
        virtual OwnerPtr<ISurface> Offset(const ISurface *pSurface, double offsetDis) const = 0;

        /// \brief  对ICurve2d 做offset， 处理自交
        /// \param const ICurve2d *pCurve2d         初始二维线
        /// \param double offsetDis        正:沿曲线方向左侧; 负:沿曲线方向右侧
        /// \return OwnerPtr<ICurve2d>     偏移后的二维线
        virtual OwnerPtr<ICurve2d> Offset(const ICurve2d *pCurve2d, double offsetDis) const = 0;
    };
}
